+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <object class="GtkWindow" id="window1">
- <property name="title" translatable="yes">Constraints — Builder</property>
- <property name="default-width">260</property>
- <child>
- <object class="ConstraintsGrid">
- <property name="layout-manager">
- <object class="GtkConstraintLayout">
- <constraints>
- <guide name="space"
- min-width="10" min-height="10"
- nat-width="100" nat-height="10"
- max-width="200" max-height="20"
- strength="strong"/>
- <constraint target="button1" target-attribute="width"
- relation="le"
- constant="200"
- strength="required"/>
- <constraint target="super" target-attribute="start"
- relation="eq"
- source="button1" source-attribute="start"
- constant="-8"
- strength="required"/>
- <constraint target="button1" target-attribute="width"
- relation="eq"
- source="button2" source-attribute="width"
- strength="required"/>
- <constraint target="button1" target-attribute="end"
- relation="eq"
- source="space" source-attribute="start"
- strength="required"/>
- <constraint target="space" target-attribute="end"
- relation="eq"
- source="button2" source-attribute="start"
- strength="required"/>
- <constraint target="super" target-attribute="end"
- relation="eq"
- source="button2" source-attribute="end"
- constant="8"
- strength="required"/>
- <constraint target="super" target-attribute="start"
- relation="eq"
- source="button3" source-attribute="start"
- constant="-8"
- strength="required"/>
- <constraint target="super" target-attribute="end"
- relation="eq"
- source="button3" source-attribute="end"
- constant="8"
- strength="required"/>
- <constraint target="super" target-attribute="top"
- relation="eq"
- source="button1" source-attribute="top"
- constant="-8"
- strength="required"/>
- <constraint target="super" target-attribute="top"
- relation="eq"
- source="button2" source-attribute="top"
- constant="-8"
- strength="required"/>
- <constraint target="button1" target-attribute="bottom"
- relation="eq"
- source="button3" source-attribute="top"
- constant="-12"
- strength="required"/>
- <constraint target="button2" target-attribute="bottom"
- relation="eq"
- source="button3" source-attribute="top"
- constant="-12"
- strength="required"/>
- <constraint target="button3" target-attribute="height"
- relation="eq"
- source="button1" source-attribute="height"
- strength="required"/>
- <constraint target="button3" target-attribute="height"
- relation="eq"
- source="button2" source-attribute="height"
- strength="required"/>
- <constraint target="super" target-attribute="bottom"
- relation="eq"
- source="button3" source-attribute="bottom"
- constant="8"
- strength="required"/>
- </constraints>
- </object>
- </property>
- <child>
- <object class="GtkButton" id="button1">
- <property name="label">Child 1</property>
- </object>
- </child>
- <child>
- <object class="GtkButton" id="button2">
- <property name="label">Child 2</property>
- </object>
- </child>
- <child>
- <object class="GtkButton" id="button3">
- <property name="label">Child 3</property>
- </object>
- </child>
- </object>
- </child>
- </object>
-</interface>
+++ /dev/null
-/* Constraints/Interactive Constraints
- * #Keywords: GtkConstraintLayout
- *
- * This example shows how constraints can be updated during user interaction.
- * The vertical edge between the buttons can be dragged with the mouse.
- */
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
-
-struct _InteractiveGrid
-{
- GtkWidget parent_instance;
-
- GtkWidget *button1, *button2;
- GtkWidget *button3;
- GtkConstraintGuide *guide;
- GtkConstraint *constraint;
-};
-
-G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
-
-static void
-interactive_grid_dispose (GObject *object)
-{
- InteractiveGrid *self = INTERACTIVE_GRID (object);
-
- g_clear_pointer (&self->button1, gtk_widget_unparent);
- g_clear_pointer (&self->button2, gtk_widget_unparent);
- g_clear_pointer (&self->button3, gtk_widget_unparent);
-
- G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
-}
-
-static void
-interactive_grid_class_init (InteractiveGridClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->dispose = interactive_grid_dispose;
-
- gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
-}
-
-static void
-build_constraints (InteractiveGrid *self,
- GtkConstraintLayout *manager)
-{
- self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
- gtk_constraint_layout_add_guide (manager, self->guide);
-
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
- GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
- GTK_CONSTRAINT_RELATION_EQ,
- 0.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
-
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (NULL,
- GTK_CONSTRAINT_ATTRIBUTE_START,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->button1),
- GTK_CONSTRAINT_ATTRIBUTE_START,
- 1.0,
- -8.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
- GTK_CONSTRAINT_ATTRIBUTE_END,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->guide),
- GTK_CONSTRAINT_ATTRIBUTE_START,
- 1.0,
- 0.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
- GTK_CONSTRAINT_ATTRIBUTE_START,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->guide),
- GTK_CONSTRAINT_ATTRIBUTE_END,
- 1.0,
- 0.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
- GTK_CONSTRAINT_ATTRIBUTE_END,
- GTK_CONSTRAINT_RELATION_EQ,
- NULL,
- GTK_CONSTRAINT_ATTRIBUTE_END,
- 1.0,
- -8.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (NULL,
- GTK_CONSTRAINT_ATTRIBUTE_START,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->button3),
- GTK_CONSTRAINT_ATTRIBUTE_START,
- 1.0,
- -8.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
-
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
- GTK_CONSTRAINT_ATTRIBUTE_END,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->guide),
- GTK_CONSTRAINT_ATTRIBUTE_START,
- 1.0,
- 0.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
-
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (NULL,
- GTK_CONSTRAINT_ATTRIBUTE_TOP,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->button1),
- GTK_CONSTRAINT_ATTRIBUTE_TOP,
- 1.0,
- -8.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
- GTK_CONSTRAINT_ATTRIBUTE_TOP,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->button1),
- GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
- 1.0,
- 0.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
- GTK_CONSTRAINT_ATTRIBUTE_TOP,
- GTK_CONSTRAINT_RELATION_EQ,
- GTK_CONSTRAINT_TARGET (self->button2),
- GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
- 1.0,
- 0.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
- gtk_constraint_layout_add_constraint (manager,
- gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
- GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
- GTK_CONSTRAINT_RELATION_EQ,
- NULL,
- GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
- 1.0,
- -8.0,
- GTK_CONSTRAINT_STRENGTH_REQUIRED));
-}
-
-static void
-drag_cb (GtkGestureDrag *drag,
- double offset_x,
- double offset_y,
- InteractiveGrid *self)
-{
- GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
- double x, y;
-
- if (self->constraint)
- {
- gtk_constraint_layout_remove_constraint (layout, self->constraint);
- g_clear_object (&self->constraint);
- }
-
- gtk_gesture_drag_get_start_point (drag, &x, &y);
- self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
- GTK_CONSTRAINT_ATTRIBUTE_LEFT,
- GTK_CONSTRAINT_RELATION_EQ,
- x + offset_x,
- GTK_CONSTRAINT_STRENGTH_REQUIRED);
- gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
- gtk_widget_queue_allocate (GTK_WIDGET (self));
-}
-
-static void
-interactive_grid_init (InteractiveGrid *self)
-{
- GtkWidget *widget = GTK_WIDGET (self);
- GtkGesture *drag;
-
- self->button1 = gtk_button_new_with_label ("Child 1");
- gtk_widget_set_parent (self->button1, widget);
- gtk_widget_set_name (self->button1, "button1");
-
- self->button2 = gtk_button_new_with_label ("Child 2");
- gtk_widget_set_parent (self->button2, widget);
- gtk_widget_set_name (self->button2, "button2");
-
- self->button3 = gtk_button_new_with_label ("Child 3");
- gtk_widget_set_parent (self->button3, widget);
- gtk_widget_set_name (self->button3, "button3");
-
- GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
- build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
-
- drag = gtk_gesture_drag_new ();
- g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
- gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
-}
-
-GtkWidget *
-do_constraints2 (GtkWidget *do_widget)
-{
- static GtkWidget *window;
-
- if (!window)
- {
- GtkWidget *box, *grid;
-
- window = gtk_window_new ();
- gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
- gtk_window_set_title (GTK_WINDOW (window), "Interactive Constraints");
- gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
- g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_window_set_child (GTK_WINDOW (window), box);
-
- grid = g_object_new (interactive_grid_get_type (), NULL);
- gtk_widget_set_hexpand (grid, TRUE);
- gtk_widget_set_vexpand (grid, TRUE);
- gtk_box_append (GTK_BOX (box), grid);
- }
-
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
- else
- gtk_window_destroy (GTK_WINDOW (window));
-
- return window;
-}
+++ /dev/null
-/* Constraints/VFL
- *
- * GtkConstraintLayout allows defining constraints using a
- * compact syntax called Visual Format Language, or VFL.
- *
- * A typical example of a VFL specification looks like this:
- *
- * H:|-[button1(==button2)]-12-[button2]-|
- */
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
-
-struct _VflGrid
-{
- GtkWidget parent_instance;
-
- GtkWidget *button1, *button2;
- GtkWidget *button3;
-};
-
-G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
-
-static void
-vfl_grid_dispose (GObject *object)
-{
- VflGrid *self = VFL_GRID (object);
-
- g_clear_pointer (&self->button1, gtk_widget_unparent);
- g_clear_pointer (&self->button2, gtk_widget_unparent);
- g_clear_pointer (&self->button3, gtk_widget_unparent);
-
- G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
-}
-
-static void
-vfl_grid_class_init (VflGridClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->dispose = vfl_grid_dispose;
-
- gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
-}
-
-/* Layout:
- *
- * +-----------------------------+
- * | +-----------+ +-----------+ |
- * | | Child 1 | | Child 2 | |
- * | +-----------+ +-----------+ |
- * | +-------------------------+ |
- * | | Child 3 | |
- * | +-------------------------+ |
- * +-----------------------------+
- *
- * Constraints:
- *
- * super.start = child1.start - 8
- * child1.width = child2.width
- * child1.end = child2.start - 12
- * child2.end = super.end - 8
- * super.start = child3.start - 8
- * child3.end = super.end - 8
- * super.top = child1.top - 8
- * super.top = child2.top - 8
- * child1.bottom = child3.top - 12
- * child2.bottom = child3.top - 12
- * child3.height = child1.height
- * child3.height = child2.height
- * child3.bottom = super.bottom - 8
- *
- * Visual format:
- *
- * H:|-8-[view1(==view2)-12-[view2]-8-|
- * H:|-8-[view3]-8-|
- * V:|-8-[view1]-12-[view3(==view1)]-8-|
- * V:|-8-[view2]-12-[view3(==view2)]-8-|
- */
-static void
-build_constraints (VflGrid *self,
- GtkConstraintLayout *manager)
-{
- const char * const vfl[] = {
- "H:|-[button1(==button2)]-12-[button2]-|",
- "H:|-[button3]-|",
- "V:|-[button1]-12-[button3(==button1)]-|",
- "V:|-[button2]-12-[button3(==button2)]-|",
- };
- GError *error = NULL;
-
- gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
- 8, 8,
- &error,
- "button1", self->button1,
- "button2", self->button2,
- "button3", self->button3,
- NULL);
- if (error != NULL)
- {
- g_printerr ("VFL parsing error:\n%s", error->message);
- g_error_free (error);
- }
-}
-
-static void
-vfl_grid_init (VflGrid *self)
-{
- GtkWidget *widget = GTK_WIDGET (self);
-
- self->button1 = gtk_button_new_with_label ("Child 1");
- gtk_widget_set_parent (self->button1, widget);
- gtk_widget_set_name (self->button1, "button1");
-
- self->button2 = gtk_button_new_with_label ("Child 2");
- gtk_widget_set_parent (self->button2, widget);
- gtk_widget_set_name (self->button2, "button2");
-
- self->button3 = gtk_button_new_with_label ("Child 3");
- gtk_widget_set_parent (self->button3, widget);
- gtk_widget_set_name (self->button3, "button3");
-
- GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
- build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
-}
-
-GtkWidget *
-do_constraints3 (GtkWidget *do_widget)
-{
- static GtkWidget *window;
-
- if (!window)
- {
- GtkWidget *box, *grid;
-
- window = gtk_window_new ();
- gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
- gtk_window_set_title (GTK_WINDOW (window), "Constraints — VFL");
- gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
- g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_window_set_child (GTK_WINDOW (window), box);
-
- grid = g_object_new (vfl_grid_get_type (), NULL);
- gtk_widget_set_hexpand (grid, TRUE);
- gtk_widget_set_vexpand (grid, TRUE);
- gtk_box_append (GTK_BOX (box), grid);
- }
-
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
- else
- gtk_window_destroy (GTK_WINDOW (window));
-
- return window;
-}
+++ /dev/null
-/* Constraints/Builder
- *
- * GtkConstraintLayouts can be created in .ui files, and constraints can be
- * set up at that time as well, as this example demonstrates. It uses the
- * same setup as the “Simple” constraints demo.
- */
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-G_DECLARE_FINAL_TYPE (ConstraintsGrid, constraints_grid, CONSTRAINTS, GRID, GtkWidget)
-
-struct _ConstraintsGrid
-{
- GtkWidget parent_instance;
-};
-
-G_DEFINE_TYPE (ConstraintsGrid, constraints_grid, GTK_TYPE_WIDGET)
-
-static void
-constraints_grid_init (ConstraintsGrid *grid)
-{
-}
-
-static void
-constraints_grid_dispose (GObject *object)
-{
- GtkWidget *widget = GTK_WIDGET (object);
- GtkWidget *child;
-
- while ((child = gtk_widget_get_first_child (widget)))
- gtk_widget_unparent (child);
-
- G_OBJECT_CLASS (constraints_grid_parent_class)->dispose (object);
-}
-
-static void
-constraints_grid_class_init (ConstraintsGridClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = constraints_grid_dispose;
-}
-
-GtkWidget *
-do_constraints4 (GtkWidget *do_widget)
-{
- static GtkWidget *window;
-
- if (!window)
- {
- GtkBuilder *builder;
-
- g_type_ensure (constraints_grid_get_type ());
-
- builder = gtk_builder_new_from_resource ("/constraints4/constraints.ui");
-
- window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
- gtk_window_set_display (GTK_WINDOW (window),
- gtk_widget_get_display (do_widget));
- g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
-
- g_object_unref (builder);
- }
-
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
- else
- gtk_window_destroy (GTK_WINDOW (window));
-
- return window;
-}
--- /dev/null
+/* Constraints/Builder
+ *
+ * GtkConstraintLayouts can be created in .ui files, and constraints can be
+ * set up at that time as well, as this example demonstrates. It uses the
+ * same setup as the “Simple” constraints demo.
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE (ConstraintsGrid, constraints_grid, CONSTRAINTS, GRID, GtkWidget)
+
+struct _ConstraintsGrid
+{
+ GtkWidget parent_instance;
+};
+
+G_DEFINE_TYPE (ConstraintsGrid, constraints_grid, GTK_TYPE_WIDGET)
+
+static void
+constraints_grid_init (ConstraintsGrid *grid)
+{
+}
+
+static void
+constraints_grid_dispose (GObject *object)
+{
+ GtkWidget *widget = GTK_WIDGET (object);
+ GtkWidget *child;
+
+ while ((child = gtk_widget_get_first_child (widget)))
+ gtk_widget_unparent (child);
+
+ G_OBJECT_CLASS (constraints_grid_parent_class)->dispose (object);
+}
+
+static void
+constraints_grid_class_init (ConstraintsGridClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = constraints_grid_dispose;
+}
+
+GtkWidget *
+do_constraints_builder (GtkWidget *do_widget)
+{
+ static GtkWidget *window;
+
+ if (!window)
+ {
+ GtkBuilder *builder;
+
+ g_type_ensure (constraints_grid_get_type ());
+
+ builder = gtk_builder_new_from_resource ("/constraints_builder/constraints_builder.ui");
+
+ window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
+ gtk_window_set_display (GTK_WINDOW (window),
+ gtk_widget_get_display (do_widget));
+ g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+
+ g_object_unref (builder);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_window_destroy (GTK_WINDOW (window));
+
+ return window;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkWindow" id="window1">
+ <property name="title" translatable="yes">Constraints — Builder</property>
+ <property name="default-width">260</property>
+ <child>
+ <object class="ConstraintsGrid">
+ <property name="layout-manager">
+ <object class="GtkConstraintLayout">
+ <constraints>
+ <guide name="space"
+ min-width="10" min-height="10"
+ nat-width="100" nat-height="10"
+ max-width="200" max-height="20"
+ strength="strong"/>
+ <constraint target="button1" target-attribute="width"
+ relation="le"
+ constant="200"
+ strength="required"/>
+ <constraint target="super" target-attribute="start"
+ relation="eq"
+ source="button1" source-attribute="start"
+ constant="-8"
+ strength="required"/>
+ <constraint target="button1" target-attribute="width"
+ relation="eq"
+ source="button2" source-attribute="width"
+ strength="required"/>
+ <constraint target="button1" target-attribute="end"
+ relation="eq"
+ source="space" source-attribute="start"
+ strength="required"/>
+ <constraint target="space" target-attribute="end"
+ relation="eq"
+ source="button2" source-attribute="start"
+ strength="required"/>
+ <constraint target="super" target-attribute="end"
+ relation="eq"
+ source="button2" source-attribute="end"
+ constant="8"
+ strength="required"/>
+ <constraint target="super" target-attribute="start"
+ relation="eq"
+ source="button3" source-attribute="start"
+ constant="-8"
+ strength="required"/>
+ <constraint target="super" target-attribute="end"
+ relation="eq"
+ source="button3" source-attribute="end"
+ constant="8"
+ strength="required"/>
+ <constraint target="super" target-attribute="top"
+ relation="eq"
+ source="button1" source-attribute="top"
+ constant="-8"
+ strength="required"/>
+ <constraint target="super" target-attribute="top"
+ relation="eq"
+ source="button2" source-attribute="top"
+ constant="-8"
+ strength="required"/>
+ <constraint target="button1" target-attribute="bottom"
+ relation="eq"
+ source="button3" source-attribute="top"
+ constant="-12"
+ strength="required"/>
+ <constraint target="button2" target-attribute="bottom"
+ relation="eq"
+ source="button3" source-attribute="top"
+ constant="-12"
+ strength="required"/>
+ <constraint target="button3" target-attribute="height"
+ relation="eq"
+ source="button1" source-attribute="height"
+ strength="required"/>
+ <constraint target="button3" target-attribute="height"
+ relation="eq"
+ source="button2" source-attribute="height"
+ strength="required"/>
+ <constraint target="super" target-attribute="bottom"
+ relation="eq"
+ source="button3" source-attribute="bottom"
+ constant="8"
+ strength="required"/>
+ </constraints>
+ </object>
+ </property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label">Child 1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label">Child 2</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button3">
+ <property name="label">Child 3</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
--- /dev/null
+/* Constraints/Interactive Constraints
+ * #Keywords: GtkConstraintLayout
+ *
+ * This example shows how constraints can be updated during user interaction.
+ * The vertical edge between the buttons can be dragged with the mouse.
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
+
+struct _InteractiveGrid
+{
+ GtkWidget parent_instance;
+
+ GtkWidget *button1, *button2;
+ GtkWidget *button3;
+ GtkConstraintGuide *guide;
+ GtkConstraint *constraint;
+};
+
+G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
+
+static void
+interactive_grid_dispose (GObject *object)
+{
+ InteractiveGrid *self = INTERACTIVE_GRID (object);
+
+ g_clear_pointer (&self->button1, gtk_widget_unparent);
+ g_clear_pointer (&self->button2, gtk_widget_unparent);
+ g_clear_pointer (&self->button3, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
+}
+
+static void
+interactive_grid_class_init (InteractiveGridClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = interactive_grid_dispose;
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
+}
+
+static void
+build_constraints (InteractiveGrid *self,
+ GtkConstraintLayout *manager)
+{
+ self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
+ gtk_constraint_layout_add_guide (manager, self->guide);
+
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
+ GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
+ GTK_CONSTRAINT_RELATION_EQ,
+ 0.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (NULL,
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->button1),
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ 1.0,
+ -8.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
+ GTK_CONSTRAINT_ATTRIBUTE_END,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->guide),
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ 1.0,
+ 0.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->guide),
+ GTK_CONSTRAINT_ATTRIBUTE_END,
+ 1.0,
+ 0.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
+ GTK_CONSTRAINT_ATTRIBUTE_END,
+ GTK_CONSTRAINT_RELATION_EQ,
+ NULL,
+ GTK_CONSTRAINT_ATTRIBUTE_END,
+ 1.0,
+ -8.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (NULL,
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->button3),
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ 1.0,
+ -8.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
+ GTK_CONSTRAINT_ATTRIBUTE_END,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->guide),
+ GTK_CONSTRAINT_ATTRIBUTE_START,
+ 1.0,
+ 0.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (NULL,
+ GTK_CONSTRAINT_ATTRIBUTE_TOP,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->button1),
+ GTK_CONSTRAINT_ATTRIBUTE_TOP,
+ 1.0,
+ -8.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
+ GTK_CONSTRAINT_ATTRIBUTE_TOP,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->button1),
+ GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
+ 1.0,
+ 0.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
+ GTK_CONSTRAINT_ATTRIBUTE_TOP,
+ GTK_CONSTRAINT_RELATION_EQ,
+ GTK_CONSTRAINT_TARGET (self->button2),
+ GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
+ 1.0,
+ 0.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+ gtk_constraint_layout_add_constraint (manager,
+ gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
+ GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
+ GTK_CONSTRAINT_RELATION_EQ,
+ NULL,
+ GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
+ 1.0,
+ -8.0,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED));
+}
+
+static void
+drag_cb (GtkGestureDrag *drag,
+ double offset_x,
+ double offset_y,
+ InteractiveGrid *self)
+{
+ GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
+ double x, y;
+
+ if (self->constraint)
+ {
+ gtk_constraint_layout_remove_constraint (layout, self->constraint);
+ g_clear_object (&self->constraint);
+ }
+
+ gtk_gesture_drag_get_start_point (drag, &x, &y);
+ self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
+ GTK_CONSTRAINT_ATTRIBUTE_LEFT,
+ GTK_CONSTRAINT_RELATION_EQ,
+ x + offset_x,
+ GTK_CONSTRAINT_STRENGTH_REQUIRED);
+ gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+}
+
+static void
+interactive_grid_init (InteractiveGrid *self)
+{
+ GtkWidget *widget = GTK_WIDGET (self);
+ GtkGesture *drag;
+
+ self->button1 = gtk_button_new_with_label ("Child 1");
+ gtk_widget_set_parent (self->button1, widget);
+ gtk_widget_set_name (self->button1, "button1");
+
+ self->button2 = gtk_button_new_with_label ("Child 2");
+ gtk_widget_set_parent (self->button2, widget);
+ gtk_widget_set_name (self->button2, "button2");
+
+ self->button3 = gtk_button_new_with_label ("Child 3");
+ gtk_widget_set_parent (self->button3, widget);
+ gtk_widget_set_name (self->button3, "button3");
+
+ GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
+ build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
+
+ drag = gtk_gesture_drag_new ();
+ g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
+ gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
+}
+
+GtkWidget *
+do_constraints_interactive (GtkWidget *do_widget)
+{
+ static GtkWidget *window;
+
+ if (!window)
+ {
+ GtkWidget *box, *grid;
+
+ window = gtk_window_new ();
+ gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
+ gtk_window_set_title (GTK_WINDOW (window), "Interactive Constraints");
+ gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
+ g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_window_set_child (GTK_WINDOW (window), box);
+
+ grid = g_object_new (interactive_grid_get_type (), NULL);
+ gtk_widget_set_hexpand (grid, TRUE);
+ gtk_widget_set_vexpand (grid, TRUE);
+ gtk_box_append (GTK_BOX (box), grid);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_window_destroy (GTK_WINDOW (window));
+
+ return window;
+}
--- /dev/null
+/* Constraints/VFL
+ *
+ * GtkConstraintLayout allows defining constraints using a
+ * compact syntax called Visual Format Language, or VFL.
+ *
+ * A typical example of a VFL specification looks like this:
+ *
+ * H:|-[button1(==button2)]-12-[button2]-|
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
+
+struct _VflGrid
+{
+ GtkWidget parent_instance;
+
+ GtkWidget *button1, *button2;
+ GtkWidget *button3;
+};
+
+G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
+
+static void
+vfl_grid_dispose (GObject *object)
+{
+ VflGrid *self = VFL_GRID (object);
+
+ g_clear_pointer (&self->button1, gtk_widget_unparent);
+ g_clear_pointer (&self->button2, gtk_widget_unparent);
+ g_clear_pointer (&self->button3, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
+}
+
+static void
+vfl_grid_class_init (VflGridClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = vfl_grid_dispose;
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
+}
+
+/* Layout:
+ *
+ * +-----------------------------+
+ * | +-----------+ +-----------+ |
+ * | | Child 1 | | Child 2 | |
+ * | +-----------+ +-----------+ |
+ * | +-------------------------+ |
+ * | | Child 3 | |
+ * | +-------------------------+ |
+ * +-----------------------------+
+ *
+ * Constraints:
+ *
+ * super.start = child1.start - 8
+ * child1.width = child2.width
+ * child1.end = child2.start - 12
+ * child2.end = super.end - 8
+ * super.start = child3.start - 8
+ * child3.end = super.end - 8
+ * super.top = child1.top - 8
+ * super.top = child2.top - 8
+ * child1.bottom = child3.top - 12
+ * child2.bottom = child3.top - 12
+ * child3.height = child1.height
+ * child3.height = child2.height
+ * child3.bottom = super.bottom - 8
+ *
+ * Visual format:
+ *
+ * H:|-8-[view1(==view2)-12-[view2]-8-|
+ * H:|-8-[view3]-8-|
+ * V:|-8-[view1]-12-[view3(==view1)]-8-|
+ * V:|-8-[view2]-12-[view3(==view2)]-8-|
+ */
+static void
+build_constraints (VflGrid *self,
+ GtkConstraintLayout *manager)
+{
+ const char * const vfl[] = {
+ "H:|-[button1(==button2)]-12-[button2]-|",
+ "H:|-[button3]-|",
+ "V:|-[button1]-12-[button3(==button1)]-|",
+ "V:|-[button2]-12-[button3(==button2)]-|",
+ };
+ GError *error = NULL;
+
+ gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
+ 8, 8,
+ &error,
+ "button1", self->button1,
+ "button2", self->button2,
+ "button3", self->button3,
+ NULL);
+ if (error != NULL)
+ {
+ g_printerr ("VFL parsing error:\n%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+vfl_grid_init (VflGrid *self)
+{
+ GtkWidget *widget = GTK_WIDGET (self);
+
+ self->button1 = gtk_button_new_with_label ("Child 1");
+ gtk_widget_set_parent (self->button1, widget);
+ gtk_widget_set_name (self->button1, "button1");
+
+ self->button2 = gtk_button_new_with_label ("Child 2");
+ gtk_widget_set_parent (self->button2, widget);
+ gtk_widget_set_name (self->button2, "button2");
+
+ self->button3 = gtk_button_new_with_label ("Child 3");
+ gtk_widget_set_parent (self->button3, widget);
+ gtk_widget_set_name (self->button3, "button3");
+
+ GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
+ build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
+}
+
+GtkWidget *
+do_constraints_vfl (GtkWidget *do_widget)
+{
+ static GtkWidget *window;
+
+ if (!window)
+ {
+ GtkWidget *box, *grid;
+
+ window = gtk_window_new ();
+ gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
+ gtk_window_set_title (GTK_WINDOW (window), "Constraints — VFL");
+ gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
+ g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_window_set_child (GTK_WINDOW (window), box);
+
+ grid = g_object_new (vfl_grid_get_type (), NULL);
+ gtk_widget_set_hexpand (grid, TRUE);
+ gtk_widget_set_vexpand (grid, TRUE);
+ gtk_box_append (GTK_BOX (box), grid);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_window_destroy (GTK_WINDOW (window));
+
+ return window;
+}
<file>demoimage.c</file>
<file>demoimage.h</file>
</gresource>
- <gresource prefix="/constraints4">
- <file>constraints.ui</file>
+ <gresource prefix="/constraints_builder">
+ <file>constraints_builder.ui</file>
</gresource>
<gresource prefix="/css_accordion">
<file>css_accordion.css</file>
<file>clipboard.c</file>
<file>combobox.c</file>
<file>constraints.c</file>
- <file>constraints2.c</file>
- <file>constraints3.c</file>
- <file>constraints4.c</file>
+ <file>constraints_interactive.c</file>
+ <file>constraints_vfl.c</file>
+ <file>constraints_builder.c</file>
<file>css_accordion.c</file>
<file>css_basics.c</file>
<file>css_blendmodes.c</file>
<file>layoutmanager2.c</file>
<file>links.c</file>
<file>listbox.c</file>
- <file>listbox2.c</file>
+ <file>listbox_controls.c</file>
<file>listview_applauncher.c</file>
<file>listview_colors.c</file>
<file>listview_clocks.c</file>
<file>markup.c</file>
<file>menu.c</file>
<file>overlay.c</file>
- <file>overlay2.c</file>
+ <file>overlay_decorative.c</file>
<file>paint.c</file>
<file>pagesetup.c</file>
<file>paintable.c</file>
<file>messages.txt</file>
<file>apple-red.png</file>
</gresource>
- <gresource prefix="/listbox2">
- <file>listbox2.ui</file>
+ <gresource prefix="/listbox_controls">
+ <file>listbox_controls.ui</file>
</gresource>
<gresource prefix="/glarea">
<file>glarea-gl.fs.glsl</file>
+++ /dev/null
-/* List Box/Controls
- *
- * GtkListBox is well-suited for creating “button strips” — lists of
- * controls for use in preference dialogs or settings panels. To create
- * this style of list, use the .rich-list style class.
- */
-
-#include <gtk/gtk.h>
-
-static GtkWidget *window;
-static GtkWidget *switch_widget;
-static GtkWidget *check;
-static GtkWidget *image;
-
-static void
-row_activated (GtkListBox *list,
- GtkListBoxRow *row)
-{
- if (gtk_widget_is_ancestor (switch_widget, GTK_WIDGET (row)))
- {
- gtk_switch_set_active (GTK_SWITCH (switch_widget),
- !gtk_switch_get_active (GTK_SWITCH (switch_widget)));
- }
- else if (gtk_widget_is_ancestor (check, GTK_WIDGET (row)))
- {
- gtk_check_button_set_active (GTK_CHECK_BUTTON (check),
- !gtk_check_button_get_active (GTK_CHECK_BUTTON (check)));
- }
- else if (gtk_widget_is_ancestor (image, GTK_WIDGET (row)))
- {
- gtk_widget_set_opacity (image,
- 1.0 - gtk_widget_get_opacity (image));
- }
-}
-
-GtkWidget *
-do_listbox2 (GtkWidget *do_widget)
-{
- if (!window)
- {
- GtkBuilderScope *scope;
- GtkBuilder *builder;
-
- scope = gtk_builder_cscope_new ();
- gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
- "row_activated", G_CALLBACK (row_activated));
- builder = gtk_builder_new ();
- gtk_builder_set_scope (builder, scope);
-
- gtk_builder_add_from_resource (builder, "/listbox2/listbox2.ui", NULL);
-
- window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
- gtk_window_set_display (GTK_WINDOW (window),
- gtk_widget_get_display (do_widget));
- g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
-
- switch_widget = GTK_WIDGET (gtk_builder_get_object (builder, "switch"));
- check = GTK_WIDGET (gtk_builder_get_object (builder, "check"));
- image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
-
- g_object_unref (builder);
- g_object_unref (scope);
- }
-
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
- else
- gtk_window_destroy (GTK_WINDOW (window));
-
- return window;
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <object class="GtkWindow" id="window">
- <property name="title" translatable="yes">List Box — Controls</property>
- <property name="default-height">400</property>
- <child>
- <object class="GtkScrolledWindow">
- <property name="hscrollbar-policy">never</property>
- <property name="min-content-height">200</property>
- <property name="hexpand">0</property>
- <property name="vexpand">1</property>
- <child>
- <object class="GtkViewport">
- <property name="scroll-to-focus">1</property>
- <child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
- <property name="margin-start">60</property>
- <property name="margin-end">60</property>
- <property name="margin-top">30</property>
- <property name="margin-bottom">30</property>
- <child>
- <object class="GtkLabel">
- <property name="label">Group 1</property>
- <property name="xalign">0</property>
- <property name="margin-bottom">10</property>
- <style>
- <class name="title-2"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkFrame">
- <child>
- <object class="GtkListBox">
- <property name="selection-mode">none</property>
- <property name="show-separators">1</property>
- <signal name="row-activated" handler="row_activated"/>
- <style>
- <class name="rich-list"/>
- </style>
-
- <child>
- <object class="GtkListBoxRow">
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="switch_label">
- <property name="label" translatable="yes">Switch</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkSwitch" id="switch">
- <property name="halign">end</property>
- <property name="valign">center</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
- <child>
- <object class="GtkListBoxRow">
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="check_label">
- <property name="label" translatable="yes">Check</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkCheckButton" id="check">
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="margin-start">10</property>
- <property name="margin-end">10</property>
- <property name="active">1</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
- <child>
- <object class="GtkListBoxRow">
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="image_label">
- <property name="label" translatable="yes">Click here!</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkImage" id="image">
- <property name="icon-name">object-select-symbolic</property>
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="margin-start">10</property>
- <property name="margin-end">10</property>
- <property name="opacity">0</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
- <child>
- <object class="GtkLabel">
- <property name="margin-top">30</property>
- <property name="margin-bottom">10</property>
- <property name="label">Group 2</property>
- <property name="xalign">0</property>
- <style>
- <class name="title-2"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkFrame">
- <child>
- <object class="GtkListBox">
- <property name="selection-mode">none</property>
- <property name="show-separators">1</property>
- <style>
- <class name="rich-list"/>
- </style>
-
- <child>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="scale_label">
- <property name="label" translatable="yes">Scale</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkScale">
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="draw-value">0</property>
- <property name="width-request">150</property>
- <property name="adjustment">
- <object class="GtkAdjustment">
- <property name="upper">100</property>
- <property name="value">50</property>
- <property name="step-increment">1</property>
- <property name="page-increment">10</property>
- </object>
- </property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
- <child>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="spin_label">
- <property name="label" translatable="yes">Spinbutton</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkSpinButton">
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="adjustment">
- <object class="GtkAdjustment">
- <property name="upper">100</property>
- <property name="value">50</property>
- <property name="step-increment">1</property>
- <property name="page-increment">10</property>
- </object>
- </property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="dropdown_label">
- <property name="label" translatable="yes">Dropdown</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkDropDown">
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="model">
- <object class="GtkStringList">
- <items>
- <item>Choice 1</item>
- <item>Choice 2</item>
- <item>Choice 3</item>
- <item>Choice 4</item>
- </items>
- </object>
- </property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
- <child>
- <object class="GtkListBoxRow">
- <property name="activatable">0</property>
- <child>
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="entry_label">
- <property name="label" translatable="yes">Entry</property>
- <property name="xalign">0</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="hexpand">1</property>
- </object>
- </child>
- <child>
- <object class="GtkEntry">
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="placeholder-text">Type here…</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkSizeGroup">
- <property name="mode">horizontal</property>
- <widgets>
- <widget name="switch_label"/>
- <widget name="check_label"/>
- <widget name="image_label"/>
- <widget name="scale_label"/>
- <widget name="spin_label"/>
- <widget name="dropdown_label"/>
- <widget name="entry_label"/>
- </widgets>
- </object>
-</interface>
--- /dev/null
+/* List Box/Controls
+ *
+ * GtkListBox is well-suited for creating “button strips” — lists of
+ * controls for use in preference dialogs or settings panels. To create
+ * this style of list, use the .rich-list style class.
+ */
+
+#include <gtk/gtk.h>
+
+static GtkWidget *window;
+static GtkWidget *switch_widget;
+static GtkWidget *check;
+static GtkWidget *image;
+
+static void
+row_activated (GtkListBox *list,
+ GtkListBoxRow *row)
+{
+ if (gtk_widget_is_ancestor (switch_widget, GTK_WIDGET (row)))
+ {
+ gtk_switch_set_active (GTK_SWITCH (switch_widget),
+ !gtk_switch_get_active (GTK_SWITCH (switch_widget)));
+ }
+ else if (gtk_widget_is_ancestor (check, GTK_WIDGET (row)))
+ {
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (check),
+ !gtk_check_button_get_active (GTK_CHECK_BUTTON (check)));
+ }
+ else if (gtk_widget_is_ancestor (image, GTK_WIDGET (row)))
+ {
+ gtk_widget_set_opacity (image,
+ 1.0 - gtk_widget_get_opacity (image));
+ }
+}
+
+GtkWidget *
+do_listbox_controls (GtkWidget *do_widget)
+{
+ if (!window)
+ {
+ GtkBuilderScope *scope;
+ GtkBuilder *builder;
+
+ scope = gtk_builder_cscope_new ();
+ gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
+ "row_activated", G_CALLBACK (row_activated));
+ builder = gtk_builder_new ();
+ gtk_builder_set_scope (builder, scope);
+
+ gtk_builder_add_from_resource (builder, "/listbox_controls/listbox_controls.ui", NULL);
+
+ window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
+ gtk_window_set_display (GTK_WINDOW (window),
+ gtk_widget_get_display (do_widget));
+ g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+
+ switch_widget = GTK_WIDGET (gtk_builder_get_object (builder, "switch"));
+ check = GTK_WIDGET (gtk_builder_get_object (builder, "check"));
+ image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
+
+ g_object_unref (builder);
+ g_object_unref (scope);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_window_destroy (GTK_WINDOW (window));
+
+ return window;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkWindow" id="window">
+ <property name="title" translatable="yes">List Box — Controls</property>
+ <property name="default-height">400</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="hscrollbar-policy">never</property>
+ <property name="min-content-height">200</property>
+ <property name="hexpand">0</property>
+ <property name="vexpand">1</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="scroll-to-focus">1</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="margin-start">60</property>
+ <property name="margin-end">60</property>
+ <property name="margin-top">30</property>
+ <property name="margin-bottom">30</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">Group 1</property>
+ <property name="xalign">0</property>
+ <property name="margin-bottom">10</property>
+ <style>
+ <class name="title-2"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <child>
+ <object class="GtkListBox">
+ <property name="selection-mode">none</property>
+ <property name="show-separators">1</property>
+ <signal name="row-activated" handler="row_activated"/>
+ <style>
+ <class name="rich-list"/>
+ </style>
+
+ <child>
+ <object class="GtkListBoxRow">
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="switch_label">
+ <property name="label" translatable="yes">Switch</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="switch">
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkListBoxRow">
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="check_label">
+ <property name="label" translatable="yes">Check</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="check">
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="margin-start">10</property>
+ <property name="margin-end">10</property>
+ <property name="active">1</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkListBoxRow">
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="image_label">
+ <property name="label" translatable="yes">Click here!</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="icon-name">object-select-symbolic</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="margin-start">10</property>
+ <property name="margin-end">10</property>
+ <property name="opacity">0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkLabel">
+ <property name="margin-top">30</property>
+ <property name="margin-bottom">10</property>
+ <property name="label">Group 2</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="title-2"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <child>
+ <object class="GtkListBox">
+ <property name="selection-mode">none</property>
+ <property name="show-separators">1</property>
+ <style>
+ <class name="rich-list"/>
+ </style>
+
+ <child>
+ <object class="GtkListBoxRow">
+ <property name="activatable">0</property>
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="scale_label">
+ <property name="label" translatable="yes">Scale</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScale">
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="draw-value">0</property>
+ <property name="width-request">150</property>
+ <property name="adjustment">
+ <object class="GtkAdjustment">
+ <property name="upper">100</property>
+ <property name="value">50</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkListBoxRow">
+ <property name="activatable">0</property>
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="spin_label">
+ <property name="label" translatable="yes">Spinbutton</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinButton">
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="adjustment">
+ <object class="GtkAdjustment">
+ <property name="upper">100</property>
+ <property name="value">50</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkListBoxRow">
+ <property name="activatable">0</property>
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="dropdown_label">
+ <property name="label" translatable="yes">Dropdown</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropDown">
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="model">
+ <object class="GtkStringList">
+ <items>
+ <item>Choice 1</item>
+ <item>Choice 2</item>
+ <item>Choice 3</item>
+ <item>Choice 4</item>
+ </items>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkListBoxRow">
+ <property name="activatable">0</property>
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkLabel" id="entry_label">
+ <property name="label" translatable="yes">Entry</property>
+ <property name="xalign">0</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">1</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry">
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="placeholder-text">Type here…</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup">
+ <property name="mode">horizontal</property>
+ <widgets>
+ <widget name="switch_label"/>
+ <widget name="check_label"/>
+ <widget name="image_label"/>
+ <widget name="scale_label"/>
+ <widget name="spin_label"/>
+ <widget name="dropdown_label"/>
+ <widget name="entry_label"/>
+ </widgets>
+ </object>
+</interface>
'clipboard.c',
'combobox.c',
'constraints.c',
- 'constraints2.c',
- 'constraints3.c',
- 'constraints4.c',
+ 'constraints_interactive.c',
+ 'constraints_vfl.c',
+ 'constraints_builder.c',
'css_accordion.c',
'css_basics.c',
'css_blendmodes.c',
'layoutmanager2.c',
'links.c',
'listbox.c',
- 'listbox2.c',
+ 'listbox_controls.c',
'menu.c',
'flowbox.c',
'list_store.c',
'listview_words.c',
'markup.c',
'overlay.c',
- 'overlay2.c',
+ 'overlay_decorative.c',
'paint.c',
'paintable.c',
'paintable_animated.c',
+++ /dev/null
-/* Overlay/Decorative Overlay
- * #Keywords: GtkOverlay
- *
- * Another example of an overlay with some decorative
- * and some interactive controls.
- */
-
-#include <gtk/gtk.h>
-
-static GtkTextTag *tag;
-
-static void
-margin_changed (GtkAdjustment *adjustment,
- GtkTextView *text)
-{
- int value;
-
- value = (int)gtk_adjustment_get_value (adjustment);
- gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text), value);
- g_object_set (tag, "pixels-above-lines", value, NULL);
-}
-
-GtkWidget *
-do_overlay2 (GtkWidget *do_widget)
-{
- static GtkWidget *window = NULL;
-
- if (!window)
- {
- GtkWidget *overlay;
- GtkWidget *sw;
- GtkWidget *text;
- GtkWidget *image;
- GtkWidget *scale;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
- GtkAdjustment *adjustment;
-
- window = gtk_window_new ();
- gtk_window_set_default_size (GTK_WINDOW (window), 500, 510);
- gtk_window_set_title (GTK_WINDOW (window), "Decorative Overlay");
-
- overlay = gtk_overlay_new ();
- sw = gtk_scrolled_window_new ();
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- text = gtk_text_view_new ();
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
-
- gtk_text_buffer_set_text (buffer, "Dear diary...", -1);
-
- tag = gtk_text_buffer_create_tag (buffer, "top-margin",
- "pixels-above-lines", 0,
- NULL);
- gtk_text_buffer_get_start_iter (buffer, &start);
- end = start;
- gtk_text_iter_forward_word_end (&end);
- gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
-
- gtk_window_set_child (GTK_WINDOW (window), overlay);
- gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
- gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), text);
- g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
-
- image = gtk_picture_new_for_resource ("/overlay2/decor1.png");
- gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
- gtk_widget_set_can_target (image, FALSE);
- gtk_widget_set_halign (image, GTK_ALIGN_START);
- gtk_widget_set_valign (image, GTK_ALIGN_START);
-
- image = gtk_picture_new_for_resource ("/overlay2/decor2.png");
- gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
- gtk_widget_set_can_target (image, FALSE);
- gtk_widget_set_halign (image, GTK_ALIGN_END);
- gtk_widget_set_valign (image, GTK_ALIGN_END);
-
- adjustment = gtk_adjustment_new (0, 0, 100, 1, 1, 0);
- g_signal_connect (adjustment, "value-changed",
- G_CALLBACK (margin_changed), text);
-
- scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
- gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
- gtk_widget_set_size_request (scale, 120, -1);
- gtk_widget_set_margin_start (scale, 20);
- gtk_widget_set_margin_end (scale, 20);
- gtk_widget_set_margin_bottom (scale, 20);
- gtk_overlay_add_overlay (GTK_OVERLAY (overlay), scale);
- gtk_widget_set_halign (scale, GTK_ALIGN_START);
- gtk_widget_set_valign (scale, GTK_ALIGN_END);
- gtk_widget_set_tooltip_text (scale, "Margin");
-
- gtk_adjustment_set_value (adjustment, 100);
- }
-
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
- else
- gtk_window_destroy (GTK_WINDOW (window));
-
- return window;
-}
--- /dev/null
+/* Overlay/Decorative Overlay
+ * #Keywords: GtkOverlay
+ *
+ * Another example of an overlay with some decorative
+ * and some interactive controls.
+ */
+
+#include <gtk/gtk.h>
+
+static GtkTextTag *tag;
+
+static void
+margin_changed (GtkAdjustment *adjustment,
+ GtkTextView *text)
+{
+ int value;
+
+ value = (int)gtk_adjustment_get_value (adjustment);
+ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text), value);
+ g_object_set (tag, "pixels-above-lines", value, NULL);
+}
+
+GtkWidget *
+do_overlay_decorative (GtkWidget *do_widget)
+{
+ static GtkWidget *window = NULL;
+
+ if (!window)
+ {
+ GtkWidget *overlay;
+ GtkWidget *sw;
+ GtkWidget *text;
+ GtkWidget *image;
+ GtkWidget *scale;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ GtkAdjustment *adjustment;
+
+ window = gtk_window_new ();
+ gtk_window_set_default_size (GTK_WINDOW (window), 500, 510);
+ gtk_window_set_title (GTK_WINDOW (window), "Decorative Overlay");
+
+ overlay = gtk_overlay_new ();
+ sw = gtk_scrolled_window_new ();
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ text = gtk_text_view_new ();
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ gtk_text_buffer_set_text (buffer, "Dear diary...", -1);
+
+ tag = gtk_text_buffer_create_tag (buffer, "top-margin",
+ "pixels-above-lines", 0,
+ NULL);
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ end = start;
+ gtk_text_iter_forward_word_end (&end);
+ gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
+
+ gtk_window_set_child (GTK_WINDOW (window), overlay);
+ gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
+ gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), text);
+ g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+
+ image = gtk_picture_new_for_resource ("/overlay2/decor1.png");
+ gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
+ gtk_widget_set_can_target (image, FALSE);
+ gtk_widget_set_halign (image, GTK_ALIGN_START);
+ gtk_widget_set_valign (image, GTK_ALIGN_START);
+
+ image = gtk_picture_new_for_resource ("/overlay2/decor2.png");
+ gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
+ gtk_widget_set_can_target (image, FALSE);
+ gtk_widget_set_halign (image, GTK_ALIGN_END);
+ gtk_widget_set_valign (image, GTK_ALIGN_END);
+
+ adjustment = gtk_adjustment_new (0, 0, 100, 1, 1, 0);
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (margin_changed), text);
+
+ scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
+ gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
+ gtk_widget_set_size_request (scale, 120, -1);
+ gtk_widget_set_margin_start (scale, 20);
+ gtk_widget_set_margin_end (scale, 20);
+ gtk_widget_set_margin_bottom (scale, 20);
+ gtk_overlay_add_overlay (GTK_OVERLAY (overlay), scale);
+ gtk_widget_set_halign (scale, GTK_ALIGN_START);
+ gtk_widget_set_valign (scale, GTK_ALIGN_END);
+ gtk_widget_set_tooltip_text (scale, "Margin");
+
+ gtk_adjustment_set_value (adjustment, 100);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_window_destroy (GTK_WINDOW (window));
+
+ return window;
+}